#ifndef GPDMA_H_
#define GPDMA_H_

/*******************************************************************************
 * File name: 		gpdma.h
 * Description: 
 * Project: 		Gpdma
 * Target: 			LPC2478
 * Compiler: 		arm-none-eabi-gcc
 * Date: 			22-08-2011
 * Author: 			kuba-pc
 * Based on: 		---
 ******************************************************************************/

/*==============================================================================
 Includes
==============================================================================*/
# include "typedef.h"
# include "irq.h"

/*==============================================================================
 Defines
==============================================================================*/

/*==============================================================================
 Globals
==============================================================================*/
enum mode {
	gpdmaM2M,                  /* memory to memory */
	gpdmaM2P,					   /* memory to peripheral */
	gpdmaP2M,						/* peripheral to memory */
	gpdmaP2P							/* peripheral to peripheral */
};

enum sbSize {
	gpdmaSB_SIZE1,		         /* source burst 1 word */
	gpdmaSB_SIZE4,		         /* source burst 4 words */
	gpdmaSB_SIZE8,		         /* source burst 8 words */
	gpdmaSB_SIZE16,	         /* and so on... */
	gpdmaSB_SIZE32,
	gpdmaSB_SIZE64,
	gpdmaSB_SIZE128,
	sgpdmaSB_SIZE256
};

enum dbSize {
	gpdmaDB_SIZE1,		         /* destination burst 1 word */
	gpdmaDB_SIZE4,		         /* destination burst 4 words */
	gpdmaDB_SIZE8,		         /* destination burst 8 words */
	gpdmaDB_SIZE16,	         /* and so on... */
	gpdmaDB_SIZE32,
	gpdmaDB_SIZE64,
	gpdmaDB_SIZE128,
	gpdmaDB_SIZE256
};

enum sWidth {
	gpdmaS_WIDTH8,			      /* source word width 8 bits */
	gpdmaS_WIDTH16,			   /* source word width 16 bits */
	gpdmaS_WIDTH32             /* source word width 32 bits */
};

enum dWidth {
	gpdmaD_WIDTH8,			      /* destination word width 8 bits */
	gpdmaD_WIDTH16,			   /* destination word width 16 bits */
	gpdmaD_WIDTH32             /* destination word width 32 bits */
};

enum srcPeriph {
	gpdmaSRC_PERIPH_SSP0TX,    /* source peripheral SSP0 TX */
	gpdmaSRC_PERIPH_SSP0RX,    /* source peripheral SSP0 RX */
	gpdmaSRC_PERIPH_SSP1TX,    /* source peripheral SSP1 TX */
	gpdmaSRC_PERIPH_SSP1RX,    /* source peripheral SSP1 RX */
	gpdmaSRC_PERIPH_SD_MMC,    /* source peripheral MMC */
	gpdmaSRC_PERIPH_I2S0,      /* source peripheral I2S0 */
	gpdmaSRC_PERIPH_I2S1       /* source peripheral I2S1 */
};

enum dstPeriph {
	gpdmaDST_PERIPH_SSP0TX,    /* destination peripheral SSP0 TX */
	gpdmaDST_PERIPH_SSP0RX,    /* destination peripheral SSP0 RX */
	gpdmaDST_PERIPH_SSP1TX,    /* destination peripheral SSP1 TX */
	gpdmaDST_PERIPH_SSP1RX,    /* destination peripheral SSP1 RX */
	gpdmaDST_PERIPH_SD_MMC,    /* destination peripheral MMC */
	gpdmaDST_PERIPH_I2S0,      /* destination peripheral I2S0 */
	gpdmaDST_PERIPH_I2S1       /* destination peripheral I2S1 */
};

enum flowCtrl {
	gpdmaFLOW_CTRL_M2M_DMA,	   /* memory to memory transfer, flow control: DMA */
	gpdmaFLOW_CTRL_M2P_DMA,	   /* memory to periph transfer, flow control: DMA */
	gpdmaFLOW_CTRL_P2M_DMA,	   /* periph to memory transfer, flow control: DMA */
	gpdmaFLOW_CTRL_P2P_DMA,	   /* periph to periph transfer, flow control: DMA */
	gpdmaFLOW_CTRL_P2P_DP,	   /* periph to periph transfer, flow control: destination periph */
	gpdmaFLOW_CTRL_M2P_P,		/* memory to periph transfer, flow control: periph */
	gpdmaFLOW_CTRL_P2M_P,		/* periph to memory transfer, flow control: periph */
	gpdmaFLOW_CTRL_P2P_SP      /* periph to periph transfer, flow control: source periph */
};

struct list {
   uint32      srcAddr;                         /* source address */
   uint32      dstAddr;                         /* destination address */
   struct list *next;                           /* pointer to next linked list item */
   uint32      ctrl;                            /* control word */
};

struct gpdmaConf {
   enum mode         mode;                      /* type of transfer */
   enum sWidth       srcWidth;                  /* source word width */
   enum dWidth       dstWidth;                  /* destination word width */
   enum sbSize       sbSize;                    /* source burst size */
   enum dbSize       dbSize;                    /* destination burst size */
   enum srcPeriph    srcPeriph;                 /* source peripheral */
   enum dstPeriph    dstPeriph;                 /* destination peripheral */
   enum flowCtrl     flowCtrl;                  /* flow control */
   uint32            srcAddr;                   /* source address */
   uint32            dstAddr;                   /* destination address */
   uint32            listItems;                 /* number of list items */
   uint32            *listSrcAddr;              /* source addresses for list */
   uint32            *listDstAddr;              /* destination addresses for list */
   void              (*transferEndService)(void); /* user service at the end of transfer */
   void              (*errorService)(void);       /* user service in case of error */
};

typedef struct gpdmaChannel *gpdmaChannel;
/*==============================================================================
 Global function prototypes
==============================================================================*/
/*------------------------------------------------------------------------------
 function name:   gpdmaInit
 description:     GPDMA module initialization
 parameters:      interrupt priority
 returned value:  none
------------------------------------------------------------------------------*/
bool gpdmaInit                (enum priority priority);

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl0Init
 description:     channel 0 initialization
 parameters:      pointer to configuration struct
 returned value:  channel settings
------------------------------------------------------------------------------*/
gpdmaChannel gpdmaChnl0Init   (const struct gpdmaConf *gpdmaConf);

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl1Init
 description:     channel 1 initialization
 parameters:      pointer to configuration struct
 returned value:  channel settings
------------------------------------------------------------------------------*/
gpdmaChannel gpdmaChnl1Init   (const struct gpdmaConf *gpdmaConf);

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl0Enable
 description:     enable channel 0
 parameters:      channel settings, size
 returned value:  none
------------------------------------------------------------------------------*/
void gpdmaChnl0Enable      (const gpdmaChannel gpdmaChnl, const uint16 size);

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl1Enable
 description:     enable channel 1
 parameters:      channel settings, size
 returned value:  none
------------------------------------------------------------------------------*/
void gpdmaChnl1Enable      (const gpdmaChannel gpdmaChnl, const uint16 size);






# if 0
/*------------------------------------------------------------------------------
 function name:   gpdmaListInit
 description:     init channels for linked list transfer
 parameters:      pointer to struct list, pointer to const struct gpdmaConf
 returned value:  gpdmaChannel object
------------------------------------------------------------------------------*/
gpdmaChannel gpdmaListInit    (struct list *list, const struct gpdmaConf *gpdmaConf);

/*------------------------------------------------------------------------------
 function name:   gpdmaStartListTrsfr
 description:     starts GPDMA transfer using linked list
 parameters:      gpdmaChannel object
 returned value:  none
------------------------------------------------------------------------------*/
void gpdmaStartListTrsfr      (const gpdmaChannel gpdmaChannel);
# endif
/******************************************************************************
* END OF FILE
******************************************************************************/

#endif /* GPDMA_H_ */
